package com.xingxue.logistics.service;

import com.xingxue.logistics.common.vo.MenuTreeNode;
import com.xingxue.logistics.common.vo.TreeNode;
import com.xingxue.logistics.common.vo.UserRoleNode;
import com.xingxue.logistics.common.vo.UserTreeNode;
import com.xingxue.logistics.dao.domain.SysMenu;
import com.xingxue.logistics.dao.domain.SysMenuExample;
import com.xingxue.logistics.dao.domain.SysRole;
import com.xingxue.logistics.dao.domain.SysRoleExample;
import com.xingxue.logistics.dao.domain.SysRoleMenu;
import com.xingxue.logistics.dao.domain.SysRoleMenuExample;
import com.xingxue.logistics.dao.domain.SysRoleUser;
import com.xingxue.logistics.dao.domain.SysRoleUserExample;
import com.xingxue.logistics.dao.domain.SysUser;
import com.xingxue.logistics.dao.mapper.SysMenuMapper;
import com.xingxue.logistics.dao.mapper.SysRoleMapper;
import com.xingxue.logistics.dao.mapper.SysRoleMenuMapper;
import com.xingxue.logistics.dao.mapper.SysRoleUserMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Kris at 2018/10/9 17:16
 */
@Service
public class LimitServiceImpl implements LimitService {

    @Autowired
    SysRoleMenuMapper roleMenuMapper;
    @Autowired
    SysRoleUserMapper roleUserMapper;
    @Autowired
    SysMenuMapper menuMapper;
    @Autowired
    SysRoleMapper roleMapper;

    @Autowired
    MenuService menuService;
    @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;

    @Override
    public List<Integer> loadMenuIdByRoleId(Integer roleId) {
        SysRoleMenuExample example = new SysRoleMenuExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        List<SysRoleMenu> sysRoleMenus = roleMenuMapper.selectByExample(example);

        List<Integer> menuIds = sysRoleMenus.stream().map(sysRoleMenu -> {
            return sysRoleMenu.getMenuId();
        }).collect(Collectors.toList());
        return menuIds;
    }

    @Override
    public List<Integer> loadMenuIdByRoleId(List<Integer> roleIds) {
        SysRoleMenuExample example = new SysRoleMenuExample();
        example.createCriteria().andRoleIdIn(roleIds);
        List<SysRoleMenu> sysRoleMenus = roleMenuMapper.selectByExample(example);

        List<Integer> menuIds = sysRoleMenus.stream().map(sysRoleMenu -> {
            return sysRoleMenu.getMenuId();
        }).collect(Collectors.toList());
        return menuIds;
    }

    @Override
    public List<SysMenu> loadMenuByIds(List<Integer> menuIds) {
        //2.根据menuId查询所有的菜单
        SysMenuExample menuExample = new SysMenuExample();
        menuExample.setOrderByClause("id asc");
        menuExample.createCriteria().andIdIn(menuIds);
        return menuMapper.selectByExample(menuExample);
    }


    @Override
    public List<Integer> loadRoleIdByUserId(Integer userId) {
        SysRoleUserExample example = new SysRoleUserExample();
        example.createCriteria().andUserIdEqualTo(userId);
        List<SysRoleUser> sysRoleUsers = roleUserMapper.selectByExample(example);
        List<Integer> roleIds = sysRoleUsers.stream().map(sysRoleUser -> {
            return sysRoleUser.getRoleId();
        }).collect(Collectors.toList());
        return  roleIds;
    }

    @Override
    public List<SysRole> loadRoleByIds(List<Integer> roleIdList) {
        SysRoleExample example = new SysRoleExample();
        example.setOrderByClause("id asc");
        example.createCriteria().andIdIn(roleIdList);
        return roleMapper.selectByExample(example);
    }


    @Override
    public List<TreeNode> loadRoleMenuTree(Integer roleId) {
        //查询所有的菜单
        List<SysMenu> all = menuService.loadAll();
        //有权限的菜单ID
        List<Integer> checkedIds = this.loadMenuIdByRoleId(roleId);

        //将菜单转换为List<TreeNode>,并且设置是否选中
        List<TreeNode> treeNodes = new LinkedList<>();
        for(SysMenu menu:all){
            Boolean isLimit = false;
            if(checkedIds.contains(menu.getId())){
                isLimit = true;
            }
            TreeNode treeNode = new TreeNode(menu.getId(), menu.getParentId(), menu.getName(), menu.getUrl(),isLimit, null);
            treeNodes.add(treeNode);
        }
        return TreeNode.buildTree(treeNodes);
    }

    @Override
    public boolean saveRoleMenu(Integer roleId, List<Integer> menuIds, Boolean checked) {
        //先删除
        SysRoleMenuExample example = new SysRoleMenuExample();
        example.createCriteria().andRoleIdEqualTo(roleId).andMenuIdIn(menuIds);
        roleMenuMapper.deleteByExample(example);
        if(checked){
            for (Integer menuId: menuIds){
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setMenuId(menuId);
                roleMenu.setRoleId(roleId);
                roleMenuMapper.insert(roleMenu);
            }
        }
        return true;
    }

    @Override
    public boolean saveRoleUser(Integer userId, List<Integer> roleIds, Boolean checked) {
        //先删除
        SysRoleUserExample example = new SysRoleUserExample();
        example.createCriteria().andRoleIdEqualTo(userId).andUserIdIn(roleIds);
        roleUserMapper.deleteByExample(example);
        if(checked){
            for (Integer roleId: roleIds){
                SysRoleUser roleUser = new SysRoleUser();
                roleUser.setUserId(userId);
                roleUser.setRoleId(roleId);
                roleUserMapper.insert(roleUser);
            }
        }
        return true;


    }

    @Override
    public List<UserRoleNode> loadRoleUserTree(Integer roleId) {
        List<SysRole> all = roleService.loadAll();
        List<Integer> checkedIds = this.loadRoleIdByUserId(roleId);

        List<UserRoleNode> userRoleNodes = new LinkedList<>();
        for(SysRole role:all){
            Boolean isLimit = false;
            if(checkedIds.contains(role.getId())){
                isLimit = true;
            }
            UserRoleNode userRoleNode = new UserRoleNode(role.getId(),isLimit,role.getName());
            userRoleNodes.add(userRoleNode);
        }
        return UserRoleNode.buildTree(userRoleNodes);
    }

    @Override
    public List<UserTreeNode> RoleUserTree(Integer roleId) {
        List<SysUser> all=userService.loadAll();
        List<Integer> checkedIds = this.loadUserIdByRoleId(roleId);
        List<UserTreeNode> treeNodes=new LinkedList<>();
        for(SysUser sysUser:all){
            Boolean isLimit = false;
            if(checkedIds.contains(sysUser.getId())){
                isLimit = true;
            }
            UserTreeNode userTreeNode=new UserTreeNode(sysUser.getId(),isLimit,sysUser.getNick());
            treeNodes.add(userTreeNode);
        }
        return UserTreeNode.buildTree(treeNodes);
    }

    private List<Integer> loadUserIdByRoleId(Integer roleId) {
        SysRoleUserExample example=new SysRoleUserExample();
        example.createCriteria().andRoleIdEqualTo(roleId);
        List<SysRoleUser> sysRoleUsers=roleUserMapper.selectByExample(example);
        List<Integer> userIds=sysRoleUsers.stream().map(sysRoleUser -> {
            return sysRoleUser.getUserId();
        }).collect(Collectors.toList());
        return userIds;
    }

    @Override
    public List<MenuTreeNode> loadRoleMenuTree2(Integer roleId) {
        List<SysMenu> all=menuService.loadAll();
        List<Integer> checkedIds = this.loadMenuIdByRoleId(roleId);
        List<MenuTreeNode> treeNodes=new LinkedList<>();
        for(SysMenu sysMenu:all){
            Boolean isLimit = false;
            if(checkedIds.contains(sysMenu.getId())){
                isLimit = true;
            }
            MenuTreeNode menuTreeNode=new MenuTreeNode(sysMenu.getId(),isLimit,sysMenu.getName());
            treeNodes.add(menuTreeNode);
        }
        return MenuTreeNode.buildTree(treeNodes);
    }
}
